package com.aspirecn.core.datacache.useragent;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
//import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
//import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;

import com.aspire.core.match.ua.object.DeviceKeyword;
import com.aspirecn.core.commons.Configuration;
import com.aspirecn.core.commons.FileUtils;
import com.aspirecn.core.commons.ObjectUtils;
import com.aspirecn.core.datacache.BaseLocalCache;
import com.csvreader.CsvReader;

/**
 * devicekeyword数据缓存
 * 
 * @author wangxinning
 * 
 */
public class DeviceKeywordCache extends BaseLocalCache {

	public final static Logger logger = Logger.getLogger(DeviceKeywordCache.class);

	// private Map<Integer, DeviceUA> deviceUAMap = new HashMap<Integer,
	// DeviceUA>();
	private List<DeviceKeyword> deviceKeywordList = new ArrayList<DeviceKeyword>();

	private static DeviceKeywordCache instance = new DeviceKeywordCache();
	
	private MMDeviceIDCache mmDeviceIDCache = MMDeviceIDCache.getInstance();

	//自定义文件
	File dataFile2 = null;
	long dataFile2crc32;
	
	private DeviceKeywordCache() {

		this.dataFile = new File(Configuration.getInstance()
				.getDownloadFilePath()
				+ File.separator
				+ "uaV3"
				+ File.separator + "devicekeyword.csv");
		this.dataFile2 = new File(Configuration.getInstance()
				.getDownloadFilePath()
				+ File.separator
				+ "uaV3"
				+ File.separator + "devicekeyword_self.csv");
		load();
	}

	public static DeviceKeywordCache getInstance() {
		return instance;
	}

	public void load() {

		if (!loading.getAndSet(true)
				&& Configuration.getInstance().switchUACache()
				&& this.dataFile.exists()) {

			this.clear();

			long start = System.currentTimeMillis();
			
			try {

				CsvReader reader = new CsvReader(this.dataFile.toString(), ',',
						Charset.forName("gbk"));

				while (reader.readRecord()) {

					if (reader.getCurrentRecord() == 0)// 设置列名
					{
						reader.setHeaders(reader.getValues());
					} else {
						DeviceKeyword keyword = new DeviceKeyword();
						
						//重写规则用
						int keywordid = NumberUtils.toInt(reader
								.get("KEYWORDID") );
						keyword.setKeywordid(keywordid);
						keyword.setDevice_id(NumberUtils.toInt(reader
								.get("DEVICE_ID")));
						keyword.setKeyword1(formatKeyword(reader.get("KEYWORD1")));
						keyword.setKeyword2(formatKeyword(reader.get("KEYWORD2")));
						keyword.setKeyword3(formatKeyword(reader.get("KEYWORD3")));

						if( Configuration.getInstance().isMM() )
						{
							//MM系统，如果不在范围，不添加入缓存
							if( !mmDeviceIDCache.isExist(keyword.getDevice_id()) )
							{
								continue;
							}
						}
						
						addDeviceKeywordList( keyword );
					}
				}
				reader.close();
				
				//加载自定义部分
				if( this.dataFile2.exists() )
				{
					dataFile2crc32 = FileUtils.checksumCRC32(this.dataFile2);
					
					CsvReader reader2 = new CsvReader(this.dataFile2.toString(), ',',
							Charset.forName("gbk"));

					while (reader2.readRecord()) {

						if (reader2.getCurrentRecord() == 0)// 设置列名
						{
							reader2.setHeaders(reader2.getValues());
						} else {
							DeviceKeyword keyword = new DeviceKeyword();
							
							int keywordid = NumberUtils.toInt(reader2
									.get("KEYWORDID") );
							keyword.setKeywordid(keywordid);
							keyword.setDevice_id(NumberUtils.toInt(reader2
									.get("DEVICE_ID")));
							
							//由于csv读取自动去掉空格，所以这里用&nbsp;取代
							keyword.setKeyword1(formatKeyword(reader2.get("KEYWORD1")));
							keyword.setKeyword2(formatKeyword(reader2.get("KEYWORD2")));
							keyword.setKeyword3(formatKeyword(reader2.get("KEYWORD3")));
							
							addDeviceKeywordList(keyword);
						}
					}
					
					reader2.close();
				}

			} catch (Exception e) {
				logger.error("DeviceKeyword信息加载异常", e);
			}

			loading.set(false);
			long end = System.currentTimeMillis();
			updateFileDownloadTime();
			logger.info("DeviceKeyword信息加载完成，time=" + (end - start) + "ms,size="
					+ deviceKeywordList.size());

		} else {
			loading.set(false);
			logger.info("配置关闭，DeviceKeyword信息未加载");
		}

		loading.set(false);
	}

	
	private void addDeviceKeywordList( DeviceKeyword keyword )
	{
		if( !ObjectUtils.isEmptyList(deviceKeywordList) )
		{
			Iterator<DeviceKeyword> ite = deviceKeywordList.iterator();
			while( ite.hasNext() )
			{
				DeviceKeyword temp = ite.next();
				if( temp.getKeywordid() == keyword.getKeywordid() && temp.getDevice_id() == keyword.getDevice_id() )
				{
					ite.remove();					
				}
			}
		}
		
		if( StringUtils.isNotBlank(keyword.getKeyword1()) )
		{
			deviceKeywordList.add(keyword);
		}
	}
	
	
	private String formatKeyword( String keyword )
	{
		String retStr = StringUtils.trimToEmpty(keyword);
		if( StringUtils.contains(retStr, "(null)") )
		{
			retStr = StringUtils.remove(retStr, "(null)");
		}
		
		if( StringUtils.contains(retStr, "&nbsp;") )
		{
			retStr = StringUtils.replace(retStr, "&nbsp;", " ");
		}
		
		return retStr;
	}
	
	
	
	@Override
	public void clear() {

		deviceKeywordList.clear();
	}

	@Override
	public void reload() {

		if (this.fileIsChange() || this.file2IsChange()) {
			this.load();
		} else {
			logger.info("没变化，DeviceKeyword信息未加载");
		}
	}
	
	//自定义文件也没变化
	private boolean file2IsChange()
	{
		if( dataFile2 == null || !dataFile2.exists() )
		{
			return false;
		}
		else
		{
			//解压文件，用这个判断
			try {
				long tempCRC32 = FileUtils.checksumCRC32(dataFile2);
				if( tempCRC32 != this.dataFile2crc32 )
				{
					return true;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return false;
	}
	
	

	public List<DeviceKeyword> getDeviceKeywordList() {
		return deviceKeywordList;
	}

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		DeviceKeywordCache geoCache = DeviceKeywordCache.getInstance();
		System.out.println(geoCache.getDeviceKeywordList().size());
		long end = System.currentTimeMillis();

		System.out.println(end - start);

	}
}